<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import Map from '@arcgis/core/Map'
import MapView from '@arcgis/core/views/MapView'
import WebTileLayer from '@arcgis/core/layers/WebTileLayer'
import DistanceMeasurement2D from '@arcgis/core/widgets/DistanceMeasurement2D'
import AreaMeasurement2D from '@arcgis/core/widgets/AreaMeasurement2D'
import gaodeLayer from '@/utils/GaoDeBaseLayer'
import { initLandslideLayer, getLandslideFeatures } from '@/services/landslideService'

// 动画效果相关
const mapViewClass = ref('')

// 地图相关
const mapContainer = ref<HTMLDivElement | null>(null)
let mapView: any = null
let landslideLayer: any = null

// 滑坡要素数据
let rawFeatures: any = []
const features = ref<any[]>([])
const filteredFeatures = ref<any[]>([])

// 控制面板状态
const controlPanelVisible = ref(true)
const activeTab = ref('filter')

// 筛选条件
const filterForm = reactive({
  riskLevel: [] as string[],
  timeRange: [] as string[],
  keyword: '',
})

// 图层控制
const baseLayerType = ref('gaode')
const layerVisibility = reactive({
  landslide: true,
})
const symbolType = ref('default')

// 工具相关
const searchAddress = ref('')
const measureType = ref('none')
let distanceMeasurement: any = null
let areaMeasurement: any = null

/**
 * 初始化地图
 */
async function initMap() {
  try {
    const map = new Map({
      basemap: {
        baseLayers: [gaodeLayer],
      },
    })

    landslideLayer = initLandslideLayer()
    map.add(landslideLayer)

    mapView = new MapView({
      map,
      center: [106.753, 31.857], // 巴中市中心
      zoom: 10,
    })

    // 确保地图容器已经挂载
    if (mapContainer.value) {
      mapView.container = mapContainer.value
    }

    // 加载滑坡要素
    await loadFeatures()
  } catch (error) {
    console.error('初始化地图失败:', error)
    ElMessage.error('地图加载失败')
  }
}

/**
 * 加载滑坡要素列表
 */
async function loadFeatures() {
  try {
    // 使用普通变量存储 ArcGIS Feature 对象
    rawFeatures = await getLandslideFeatures()

    // 将 ArcGIS Feature 对象转换为普通 JavaScript 对象
    features.value = rawFeatures.map((feature: any) => convertFeatureToPlainObject(feature))

    // 初始时显示所有要素
    filteredFeatures.value = features.value

    console.log('加载滑坡要素成功，共', features.value.length, '条')
  } catch (e) {
    console.error('加载滑坡要素失败:', e)
    ElMessage.error('滑坡要素加载失败')
    rawFeatures = []
    features.value = []
  }
}

/**
 * 将 ArcGIS Feature 对象转换为普通 JavaScript 对象
 */
function convertFeatureToPlainObject(feature: any) {
  if (!feature) return null

  return {
    id: feature.attributes.OBJECTID,
    attributes: {
      name: feature.attributes.name || '',
      Address: feature.attributes.Address || '',
      occuredTime: feature.attributes.occuredTime || '',
      Description: feature.attributes.Description || '',
      riskLevel: feature.attributes.riskLevel || '低风险',
    },
    geometry: {
      longitude: feature.geometry ? feature.geometry.longitude : null,
      latitude: feature.geometry ? feature.geometry.latitude : null,
    },
  }
}

/**
 * 应用筛选条件
 */
function applyFilter() {
  // 如果没有设置任何筛选条件，显示所有要素
  if (filterForm.riskLevel.length === 0 && !filterForm.timeRange.length && !filterForm.keyword) {
    filteredFeatures.value = features.value
    updateMapDisplay()
    ElMessage.success('已显示所有滑坡要素')
    return
  }

  // 应用筛选条件
  filteredFeatures.value = features.value.filter((feature: any) => {
    // 风险等级筛选
    if (
      filterForm.riskLevel.length > 0 &&
      !filterForm.riskLevel.includes(feature.attributes.riskLevel)
    ) {
      return false
    }

    // 时间范围筛选
    if (filterForm.timeRange && filterForm.timeRange.length === 2) {
      const occuredTime = feature.attributes.occuredTime.split(' ')[0] // 只取日期部分
      const startDate = filterForm.timeRange[0]
      const endDate = filterForm.timeRange[1]

      if (occuredTime < startDate || occuredTime > endDate) {
        return false
      }
    }

    // 关键词搜索
    if (filterForm.keyword) {
      const keyword = filterForm.keyword.toLowerCase()
      const name = (feature.attributes.name || '').toLowerCase()
      const address = (feature.attributes.Address || '').toLowerCase()
      const description = (feature.attributes.Description || '').toLowerCase()

      if (!name.includes(keyword) && !address.includes(keyword) && !description.includes(keyword)) {
        return false
      }
    }

    return true
  })

  // 更新地图显示
  updateMapDisplay()

  ElMessage.success(`筛选完成，共找到 ${filteredFeatures.value.length} 个滑坡要素`)
}

/**
 * 重置筛选条件
 */
function resetFilter() {
  // 重置筛选表单
  filterForm.riskLevel = []
  filterForm.timeRange = []
  filterForm.keyword = ''

  // 显示所有要素
  filteredFeatures.value = features.value
  updateMapDisplay()

  ElMessage.info('已重置筛选条件')
}

/**
 * 更新地图显示
 */
function updateMapDisplay() {
  if (!landslideLayer) return

  // 创建一个对象ID集合，用于筛选图层
  const objectIds = filteredFeatures.value.map((feature: any) => feature.id)

  // 设置图层的定义表达式
  if (objectIds.length > 0) {
    landslideLayer.definitionExpression = `OBJECTID IN (${objectIds.join(',')})`
  } else {
    // 如果没有符合条件的要素，设置一个不可能满足的条件
    landslideLayer.definitionExpression = '1=2'
  }
}

/**
 * 切换控制面板显示状态
 */
function toggleControlPanel() {
  controlPanelVisible.value = !controlPanelVisible.value
}

/**
 * 切换图层可见性
 * @param layerName 图层名称
 */
function toggleLayerVisibility(layerName: string) {
  if (layerName === 'landslide' && landslideLayer) {
    landslideLayer.visible = layerVisibility.landslide
  }
}

/**
 * 更改基础图层
 */
function changeBaseLayer() {
  if (!mapView) return

  // 移除当前基础图层
  if (mapView.map.basemap.baseLayers.length > 0) {
    mapView.map.basemap.baseLayers.removeAll()
  }

  // 添加新的基础图层
  if (baseLayerType.value === 'gaode') {
    // 高德地图
    mapView.map.basemap.baseLayers.add(gaodeLayer)
  } else if (baseLayerType.value === 'satellite') {
    // 卫星影像（这里使用高德卫星图层，实际应用中可以替换为真实的卫星图层）
    const satelliteLayer = new WebTileLayer({
      urlTemplate: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
      copyright: '高德卫星影像',
    })
    mapView.map.basemap.baseLayers.add(satelliteLayer)
  }
}

/**
 * 更改符号类型
 */
function changeSymbolType() {
  if (!landslideLayer) return

  if (symbolType.value === 'risk') {
    // 根据风险等级设置不同的符号
    const renderer = {
      type: 'unique-value',
      field: 'riskLevel',
      defaultSymbol: {
        type: 'simple-marker',
        color: [128, 128, 128], // 灰色
        size: 8,
        outline: {
          color: [255, 255, 255],
          width: 1,
        },
      },
      uniqueValueInfos: [
        {
          value: '低风险',
          symbol: {
            type: 'simple-marker',
            color: [76, 175, 80], // 绿色
            size: 8,
            outline: {
              color: [255, 255, 255],
              width: 1,
            },
          },
        },
        {
          value: '中风险',
          symbol: {
            type: 'simple-marker',
            color: [255, 235, 59], // 黄色
            size: 10,
            outline: {
              color: [255, 255, 255],
              width: 1,
            },
          },
        },
        {
          value: '高风险',
          symbol: {
            type: 'simple-marker',
            color: [255, 152, 0], // 橙色
            size: 12,
            outline: {
              color: [255, 255, 255],
              width: 1,
            },
          },
        },
        {
          value: '极高风险',
          symbol: {
            type: 'simple-marker',
            color: [244, 67, 54], // 红色
            size: 14,
            outline: {
              color: [255, 255, 255],
              width: 1,
            },
          },
        },
      ],
    }

    landslideLayer.renderer = renderer
  } else {
    // 使用默认符号
    landslideLayer.renderer = {
      type: 'simple',
      symbol: {
        type: 'simple-marker',
        color: [226, 119, 40],
        size: 12,
        outline: {
          color: [255, 255, 255],
          width: 2,
        },
      },
    }
  }
}

/**
 * 获取高风险滑坡数量
 */
function getHighRiskCount() {
  return features.value.filter(
    (feature) =>
      feature.attributes.riskLevel === '高风险' || feature.attributes.riskLevel === '极高风险',
  ).length
}

/**
 * 获取最近更新时间
 */
function getLatestUpdateTime() {
  if (features.value.length === 0) return '暂无数据'

  // 找出最新的滑坡事件
  const latestFeature = features.value.reduce((latest, current) => {
    if (!latest) return current

    const latestTime = latest.attributes.occuredTime || ''
    const currentTime = current.attributes.occuredTime || ''

    return currentTime > latestTime ? current : latest
  }, null)

  return latestFeature?.attributes.occuredTime || '暂无数据'
}

/**
 * 地图放大
 */
function zoomIn() {
  if (mapView) {
    mapView.zoom += 1
  }
}

/**
 * 地图缩小
 */
function zoomOut() {
  if (mapView) {
    mapView.zoom -= 1
  }
}

/**
 * 重置地图视图
 */
function resetMapView() {
  if (mapView) {
    mapView.goTo({
      center: [106.753, 31.857],
      zoom: 10,
    })
  }
}

/**
 * 搜索地址
 */
async function searchLocation() {
  if (!searchAddress.value || !mapView) return

  try {
    // 这里简化处理，实际应用中应该调用高德地图的地理编码API
    ElMessage.info('正在搜索地址: ' + searchAddress.value)

    // 模拟搜索结果
    const randomLng = 106.753 + (Math.random() - 0.5) * 0.5
    const randomLat = 31.857 + (Math.random() - 0.5) * 0.5

    // 移动到搜索位置
    mapView.goTo({
      center: [randomLng, randomLat],
      zoom: 13,
    })

    // 显示搜索结果
    ElMessage.success('已定位到搜索位置')
  } catch (error) {
    console.error('搜索地址失败:', error)
    ElMessage.error('地址搜索失败')
  }
}

/**
 * 切换测量工具
 */
function toggleMeasureTool() {
  if (!mapView) return

  // 移除现有的测量部件
  if (distanceMeasurement) {
    distanceMeasurement.visible = false
  }

  if (areaMeasurement) {
    areaMeasurement.visible = false
  }

  if (measureType.value === 'none') {
    ElMessage.info('已关闭测量工具')
    return
  }

  if (measureType.value === 'distance') {
    // 如果距离测量部件不存在，创建一个新的
    if (!distanceMeasurement) {
      distanceMeasurement = new DistanceMeasurement2D({
        view: mapView,
        unit: 'kilometers',
      })
      mapView.ui.add(distanceMeasurement, 'bottom-right')
    }

    // 显示距离测量部件
    distanceMeasurement.visible = true

    // 开始新的测量
    distanceMeasurement.viewModel.newMeasurement()

    ElMessage.info('已启用距离测量工具，请在地图上点击开始测量')
  } else if (measureType.value === 'area') {
    // 如果面积测量部件不存在，创建一个新的
    if (!areaMeasurement) {
      areaMeasurement = new AreaMeasurement2D({
        view: mapView,
        unit: 'square-kilometers',
      })
      mapView.ui.add(areaMeasurement, 'bottom-right')
    }

    // 显示面积测量部件
    areaMeasurement.visible = true

    // 开始新的测量
    areaMeasurement.viewModel.newMeasurement()

    ElMessage.info('已启用面积测量工具，请在地图上点击开始测量')
  }
}

/**
 * 导出地图
 */
function exportMap() {
  if (!mapView) return

  // 这里简化处理，实际应用中应该实现真正的导出功能
  ElMessage.success('地图导出功能开发中...')
}

/**
 * 组件挂载时的初始化
 */
onMounted(async () => {
  // 初始化地图
  await initMap()

  // 添加进入动画类
  setTimeout(() => {
    mapViewClass.value = 'map-view-show'
  }, 100)
})

/**
 * 组件卸载前的清理
 */
onBeforeUnmount(() => {
  if (distanceMeasurement) {
    distanceMeasurement = null
  }

  if (areaMeasurement) {
    areaMeasurement = null
  }

  if (mapView) {
    mapView = null
  }
})
</script>

<template>
  <div class="map-view" :class="mapViewClass">
    <div class="page-header">
      <h2>滑坡风险地图</h2>
      <div class="header-actions">
        <el-button type="primary" size="small" @click="toggleControlPanel">
          <el-icon><Operation /></el-icon>
          {{ controlPanelVisible ? '隐藏控制面板' : '显示控制面板' }}
        </el-button>
      </div>
    </div>

    <div class="map-layout">
      <!-- 控制面板 -->
      <div class="control-panel" v-show="controlPanelVisible">
        <el-tabs v-model="activeTab" class="control-tabs">
          <el-tab-pane label="筛选" name="filter">
            <div class="tab-content">
              <el-form label-position="top">
                <!-- 风险等级筛选 -->
                <el-form-item label="风险等级">
                  <el-checkbox-group v-model="filterForm.riskLevel">
                    <el-checkbox label="低风险">
                      <el-tag size="small" type="success">低风险</el-tag>
                    </el-checkbox>
                    <el-checkbox label="中风险">
                      <el-tag size="small" type="warning">中风险</el-tag>
                    </el-checkbox>
                    <el-checkbox label="高风险">
                      <el-tag size="small" type="danger">高风险</el-tag>
                    </el-checkbox>
                    <el-checkbox label="极高风险">
                      <el-tag size="small" type="danger" effect="dark">极高风险</el-tag>
                    </el-checkbox>
                  </el-checkbox-group>
                </el-form-item>

                <!-- 时间范围筛选 -->
                <el-form-item label="发生时间范围">
                  <el-date-picker
                    v-model="filterForm.timeRange"
                    type="daterange"
                    range-separator="至"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    format="YYYY-MM-DD"
                    value-format="YYYY-MM-DD"
                    style="width: 100%"
                  />
                </el-form-item>

                <!-- 关键词搜索 -->
                <el-form-item label="关键词搜索">
                  <el-input
                    v-model="filterForm.keyword"
                    placeholder="输入地址或名称关键词"
                    clearable
                  >
                    <template #prefix>
                      <el-icon><Search /></el-icon>
                    </template>
                  </el-input>
                </el-form-item>

                <!-- 筛选按钮 -->
                <el-form-item>
                  <el-button type="primary" @click="applyFilter">应用筛选</el-button>
                  <el-button @click="resetFilter">重置</el-button>
                </el-form-item>
              </el-form>
            </div>
          </el-tab-pane>
          <el-tab-pane label="图层" name="layers">
            <div class="tab-content">
              <el-form label-position="top">
                <!-- 图层控制 -->
                <el-form-item label="基础图层">
                  <el-radio-group v-model="baseLayerType" @change="changeBaseLayer">
                    <el-radio-button label="gaode">高德地图</el-radio-button>
                    <el-radio-button label="satellite">卫星影像</el-radio-button>
                  </el-radio-group>
                </el-form-item>

                <!-- 滑坡要素图层控制 -->
                <el-form-item label="滑坡要素图层">
                  <el-switch
                    v-model="layerVisibility.landslide"
                    active-text="显示"
                    inactive-text="隐藏"
                    @change="toggleLayerVisibility('landslide')"
                  />
                </el-form-item>

                <!-- 风险等级样式 -->
                <el-form-item label="风险等级样式">
                  <el-radio-group v-model="symbolType" @change="changeSymbolType">
                    <el-radio label="default">默认样式</el-radio>
                    <el-radio label="risk">风险等级</el-radio>
                  </el-radio-group>
                </el-form-item>

                <!-- 图例 -->
                <el-form-item label="图例">
                  <div class="legend-container">
                    <div class="legend-item">
                      <div class="legend-symbol" style="background-color: #4caf50"></div>
                      <div class="legend-label">低风险</div>
                    </div>
                    <div class="legend-item">
                      <div class="legend-symbol" style="background-color: #ffeb3b"></div>
                      <div class="legend-label">中风险</div>
                    </div>
                    <div class="legend-item">
                      <div class="legend-symbol" style="background-color: #ff9800"></div>
                      <div class="legend-label">高风险</div>
                    </div>
                    <div class="legend-item">
                      <div class="legend-symbol" style="background-color: #f44336"></div>
                      <div class="legend-label">极高风险</div>
                    </div>
                  </div>
                </el-form-item>
              </el-form>
            </div>
          </el-tab-pane>
          <el-tab-pane label="工具" name="tools">
            <div class="tab-content">
              <el-form label-position="top">
                <!-- 地图工具 -->
                <el-form-item label="地图操作">
                  <el-button-group>
                    <el-button type="primary" @click="zoomIn">
                      <el-icon><ZoomIn /></el-icon> 放大
                    </el-button>
                    <el-button type="primary" @click="zoomOut">
                      <el-icon><ZoomOut /></el-icon> 缩小
                    </el-button>
                    <el-button type="primary" @click="resetMapView">
                      <el-icon><RefreshRight /></el-icon> 重置
                    </el-button>
                  </el-button-group>
                </el-form-item>

                <!-- 地址搜索 -->
                <el-form-item label="地址搜索">
                  <div class="search-box">
                    <el-input
                      v-model="searchAddress"
                      placeholder="输入地址进行搜索"
                      clearable
                      @keyup.enter="searchLocation"
                    >
                      <template #append>
                        <el-button @click="searchLocation">
                          <el-icon><Search /></el-icon>
                        </el-button>
                      </template>
                    </el-input>
                  </div>
                </el-form-item>

                <!-- 测量工具 -->
                <el-form-item label="测量工具">
                  <el-radio-group v-model="measureType" @change="toggleMeasureTool">
                    <el-radio-button label="none">关闭</el-radio-button>
                    <el-radio-button label="distance">距离</el-radio-button>
                    <el-radio-button label="area">面积</el-radio-button>
                  </el-radio-group>
                </el-form-item>

                <!-- 导出功能 -->
                <el-form-item label="导出地图">
                  <el-button type="success" @click="exportMap">
                    <el-icon><Download /></el-icon> 导出当前视图
                  </el-button>
                </el-form-item>
              </el-form>
            </div>
          </el-tab-pane>
          <el-tab-pane label="信息" name="info">
            <div class="tab-content">
              <div class="info-section">
                <h3>滑坡风险信息</h3>
                <el-divider />
                <div class="info-content">
                  <p><strong>总滑坡数量:</strong> {{ features.length }} 个</p>
                  <p><strong>高风险滑坡:</strong> {{ getHighRiskCount() }} 个</p>
                  <p><strong>最近更新:</strong> {{ getLatestUpdateTime() }}</p>
                </div>
              </div>

              <div class="info-section">
                <h3>使用说明</h3>
                <el-divider />
                <div class="info-content">
                  <p>
                    <el-icon><InfoFilled /></el-icon>
                    <strong>筛选功能:</strong> 可按风险等级、时间范围和关键词筛选滑坡要素
                  </p>
                  <p>
                    <el-icon><InfoFilled /></el-icon>
                    <strong>图层控制:</strong> 可切换地图底图、控制图层显示和更改符号样式
                  </p>
                  <p>
                    <el-icon><InfoFilled /></el-icon>
                    <strong>工具功能:</strong> 提供地图缩放、地址搜索和测量工具
                  </p>
                  <p>
                    <el-icon><InfoFilled /></el-icon>
                    <strong>点击要素:</strong> 点击地图上的滑坡点可查看详细信息
                  </p>
                </div>
              </div>

              <div class="info-section">
                <h3>风险等级说明</h3>
                <el-divider />
                <div class="risk-levels">
                  <div class="risk-level-item">
                    <el-tag size="large" type="success">低风险</el-tag>
                    <span>滑坡可能性低，影响范围小</span>
                  </div>
                  <div class="risk-level-item">
                    <el-tag size="large" type="warning">中风险</el-tag>
                    <span>滑坡可能性中等，需要关注</span>
                  </div>
                  <div class="risk-level-item">
                    <el-tag size="large" type="danger">高风险</el-tag>
                    <span>滑坡可能性高，需要采取防范措施</span>
                  </div>
                  <div class="risk-level-item">
                    <el-tag size="large" type="danger" effect="dark">极高风险</el-tag>
                    <span>滑坡可能性极高，需要紧急防范</span>
                  </div>
                </div>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>

      <!-- 地图容器 -->
      <div class="map-container">
        <div ref="mapContainer" class="map-view-container"></div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.legend-container {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.legend-item {
  display: flex;
  align-items: center;
  margin-right: 15px;
}

.legend-symbol {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  margin-right: 5px;
}

.legend-label {
  font-size: 12px;
  color: #666;
}
.map-view {
  opacity: 0;
  transform: translateY(20px);
  transition: all 0.5s ease;
  height: 100%;

  &.map-view-show {
    opacity: 1;
    transform: translateY(0);
  }
}

.info-section {
  margin-bottom: 20px;

  h3 {
    color: #b71c1c;
    font-size: 16px;
    margin: 0;
  }

  .info-content {
    padding: 10px 0;

    p {
      margin: 8px 0;
      display: flex;
      align-items: center;

      .el-icon {
        margin-right: 5px;
        color: #e65100;
      }
    }
  }

  .risk-levels {
    padding: 10px 0;

    .risk-level-item {
      display: flex;
      align-items: center;
      margin-bottom: 10px;

      .el-tag {
        margin-right: 10px;
        width: 80px;
        justify-content: center;
      }
    }
  }
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;

  h2 {
    color: #b71c1c;
    margin: 0;
  }

  .header-actions {
    display: flex;
    gap: 8px;
  }
}

.map-layout {
  display: flex;
  height: calc(100vh - 180px);
  gap: 16px;

  .control-panel {
    width: 300px;
    background-color: #fff;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    overflow: hidden;

    .control-tabs {
      height: 100%;

      :deep(.el-tabs__content) {
        padding: 16px;
        height: calc(100% - 55px);
        overflow-y: auto;
      }

      .tab-content {
        height: 100%;
      }
    }
  }

  .map-container {
    flex: 1;
    background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    overflow: hidden;

    .map-view-container {
      width: 100%;
      height: 100%;
    }
  }
}
</style>
